﻿using System;
using System.Collections.Generic;
using Jayden.Dll.Web.Helper;
using Jayden.Dll.Web.HtmlControls;
using Jayden.Dll.Web.HtmlControls.Generics;

namespace Jayden.Dll.Web.Controls
{
	public class DataTable : DataTable<object> { }

	public class DataTable<T> : Table
	{
		public delegate IEnumerable<HtmlControl> ContentBuilder(T value, Column column, int index);

		public static IEnumerable<HtmlControl> OneControl(HtmlControl control) { yield return control; }
		public static IEnumerable<HtmlControl> ParseHtml(string html) { return HtmlControl.LoadHtmlControls(html, null, TdDescription.Instance); }
		public static IEnumerable<HtmlControl> ParseText(string text) { yield return new HtmlText(text); }

		public static Comparison<T> DefaultComparison = delegate(T o1, T o2)
		{
			if (o1 == null && o2 == null)
				return 0;
			if (o1 == null)
				return -1;
			if (o2 == null)
				return 1;
			if (o1 is IComparable<T>)
				return ((IComparable<T>) o1).CompareTo(o2);
			return o1.ToString().CompareTo(o2.ToString());
		};
		public class Column
		{
			private string m_HeaderCaption;
			private uint? m_Width;
			private ContentBuilder m_ContentBuilder;
			private Comparison<T> m_Comparison;
			private bool m_HtmlEncode;
			private bool m_LoadControls;

			public Column(string caption, uint? width, ContentBuilder contentBuilder, Comparison<T> comparison, bool htmlEncode = true, bool loadControls = false)
			{
				m_HeaderCaption = caption;
				m_Width = width;
				m_ContentBuilder = contentBuilder;
				m_HtmlEncode = htmlEncode;
				m_LoadControls = loadControls;
				m_Comparison = comparison;
			}

			public string HeaderCaption { get { return m_HeaderCaption; } }
			public uint? Width { get { return m_Width; } }
			public ContentBuilder ContentBuilder { get { return m_ContentBuilder; } }
			public bool HtmlEncode { get { return m_HtmlEncode; } }
			public bool LoadControls { get { return m_LoadControls; } }
			public Comparison<T> Comparison { get { return m_Comparison; } }
			public Comparison<T> ReverseComparison
			{
				get
				{
					if (m_Comparison == null)
						return null;
					return delegate(T o1, T o2) {
						return m_Comparison(o2, o1);
					};
				}
			}
		}

		private List<Column> m_Columns;

		public Column AddColumn(Column c)
		{
			if (m_Columns == null)
				m_Columns = new List<Column>();
			m_Columns.Add(c);
			return c;
		}
		public Column AddColumn(string caption, uint? width, ContentBuilder format, Comparison<T> comparison, bool htmlEncode = true, bool loadControls = false)
		{
			Column c = new Column(caption, width, format, comparison, htmlEncode, loadControls);
			return AddColumn(c);
		}
		public Column GetColumn(int columnIndex) { return m_Columns[columnIndex]; }
		public int ColumnsCount { get { return m_Columns == null ? 0 : m_Columns.Count; } }
		public string GetTableSizeFromColumns()
		{
			uint total = 0;
			foreach (Column c in m_Columns)
				total += c.Width.HasValue ? c.Width.Value : 50;
			return HtmlHelper.ToPixels(total);
		}

		public Th[] AddHeaders(bool revesreOnClick = true)
		{
			Tr tr = AddTr();
			List<Th> ths = new List<Th>();
			for (int c = 0; c < m_Columns.Count; c++)
			{
				Column col = m_Columns[c];
				string text = col.HeaderCaption;
				Th th = tr.AddTh();
				if (col.Comparison != null)
					th.AddA(col.HeaderCaption, "?" + Id + (revesreOnClick ? "Reverse" : "") + "Sort=" + c);
				else
					th.AddText(col.HeaderCaption);
				if (col.Width.HasValue)
					th.CssProperties.Add("width", col.Width.Value + "px");
				ths.Add(th);
			}
			return ths.ToArray();
		}

		public Tr AddTr(T value)
		{
			Tr tr = AddTr();
			for (int c = 0; c < m_Columns.Count; c++)
			{
				Column col = m_Columns[c];
				Td td = tr.AddTd();
				foreach (HtmlControl control in col.ContentBuilder(value, col, c))
					td.AddControl(control);
			}
			return tr;
		}

	}

}
